Source code for nlp_architect.data.cdc_resources.relations.referent_dict_relation_extraction

# ******************************************************************************
# Copyright 2017-2018 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ******************************************************************************

import logging
import os
from typing import Dict, List, Set

from nlp_architect.common.cdc.mention_data import MentionDataLight
from nlp_architect.data.cdc_resources.relations.relation_extraction import RelationExtraction
from nlp_architect.data.cdc_resources.relations.relation_types_enums import \
    OnlineOROfflineMethod, RelationType
from nlp_architect.utils.io import load_json_file
from nlp_architect.utils.string_utils import StringUtils

logger = logging.getLogger(__name__)


[docs]class ReferentDictRelationExtraction(RelationExtraction): def __init__(self, method: OnlineOROfflineMethod = OnlineOROfflineMethod.ONLINE, ref_dict: str = None): """ Extract Relation between two mentions according to Referent Dictionary knowledge Args: method (optional): OnlineOROfflineMethod.{ONLINE/OFFLINE} run against full referent dictionary or a sub-set of (default = ONLINE) ref_dict (required): str Location of referent dictionary file to work with """ logger.info('Loading ReferentDict module') if ref_dict is not None and os.path.isfile(ref_dict): if method == OnlineOROfflineMethod.OFFLINE: self.ref_dict = load_json_file(ref_dict) elif method == OnlineOROfflineMethod.ONLINE: self.ref_dict = self.load_reference_dict(ref_dict) logger.info('ReferentDict module lead successfully') else: raise FileNotFoundError('Referent Dict file not found or not in path:' + ref_dict) super(ReferentDictRelationExtraction, self).__init__()
[docs] def extract_all_relations(self, mention_x: MentionDataLight, mention_y: MentionDataLight) -> Set[RelationType]: ret_ = set() ret_.add(self.extract_sub_relations(mention_x, mention_y, RelationType.REFERENT_DICT)) return ret_
[docs] def extract_sub_relations(self, mention_x: MentionDataLight, mention_y: MentionDataLight, relation: RelationType) -> RelationType: """ Check if input mentions has the given relation between them Args: mention_x: MentionDataLight mention_y: MentionDataLight relation: RelationType Returns: RelationType: relation in case mentions has given relation or RelationType.NO_RELATION_FOUND otherwise """ if relation is not RelationType.REFERENT_DICT: return RelationType.NO_RELATION_FOUND mention_x_str = mention_x.tokens_str mention_y_str = mention_y.tokens_str if StringUtils.is_pronoun(mention_x_str.lower()) or StringUtils.is_pronoun( mention_y_str.lower()): return RelationType.NO_RELATION_FOUND if self.is_referent_dict(mention_x, mention_y): return RelationType.REFERENT_DICT return RelationType.NO_RELATION_FOUND
[docs] def is_referent_dict(self, mention_x: MentionDataLight, mention_y: MentionDataLight) -> bool: """ Check if input mentions has referent dictionary relation between them Args: mention_x: MentionDataLight mention_y: MentionDataLight Returns: bool """ match_result = False x_head = mention_x.mention_head y_head = mention_y.mention_head x_head_lemma = mention_x.mention_head_lemma y_head_lemma = mention_y.mention_head_lemma if (x_head in self.ref_dict and y_head in self.ref_dict[x_head]) or ( y_head in self.ref_dict and x_head in self.ref_dict[y_head]): match_result = True if (x_head_lemma in self.ref_dict and y_head_lemma in self.ref_dict[x_head_lemma]) or \ (y_head_lemma in self.ref_dict and x_head_lemma in self.ref_dict[y_head_lemma]): match_result = True if (x_head_lemma in self.ref_dict and y_head in self.ref_dict[x_head_lemma]) or ( y_head_lemma in self.ref_dict and x_head in self.ref_dict[y_head_lemma]): match_result = True if (y_head in self.ref_dict and x_head_lemma in self.ref_dict[y_head]) or \ (x_head in self.ref_dict and y_head_lemma in self.ref_dict[x_head]): match_result = True return match_result
[docs] @staticmethod def get_supported_relations(): """ Return all supported relations by this class Returns: List[RelationType] """ return [RelationType.REFERENT_DICT]
[docs] @staticmethod def load_reference_dict(dict_fname: str) -> Dict[str, List[str]]: """ Method to load referent dictionary to memory Returns: List[RelationType] """ word_dict = {} first = True with open(dict_fname, 'r', encoding="utf-8") as f: for line in f: if first: first = False continue word1, word2, _, npmi = line.strip().split('\t') npmi = float(npmi) if npmi >= 0.2: if word1 not in word_dict: word_dict[word1] = [] word_dict[word1].append(word2) return word_dict